﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SQLite;
using System.Windows.Media.Imaging;

namespace MOJsdk
{
    public class MOJMovie : MOJBasicMovieClass, IComparable
    {
        private IHost _host;
        private List<MOJFile> _files;

        public MOJMovie(string TheMovieCode)
        {
            try
            {
                _host = GlobalVars.TheHost;

                using (SQLiteConnection _cn = new SQLiteConnection(_host.SystemVars.DataBaseLocal))
                {
                    MOJBasicMovieClass m = _cn.Table<MOJBasicMovieClass>().Where(mz => mz.MovieCode == TheMovieCode).First();
                    this.CoverID = m.CoverID;
                    this.IMDBID = m.IMDBID;
                    this.MovieCast = m.MovieCast;
                    this.MovieCode = m.MovieCode;
                    this.MovieDirectors = m.MovieDirectors;
                    this.MovieGenres = m.MovieGenres;
                    this.MovieTitle = m.MovieTitle;
                    this.MovieWriters = m.MovieWriters;
                    this.MovieYear = m.MovieYear;
                    this.OriginalTitle = m.OriginalTitle;
                    this.Tagline = m.Tagline;

                    List<MOJBasicFileClass> tfiles = new List<MOJBasicFileClass>(_cn.Table<MOJBasicFileClass>().Where(f => f.MovieCode == this.MovieCode));
                    
                    _files = new List<MOJFile>();
                    
                    foreach (var v in tfiles)
                        _files.Add(new MOJFile(v));
                    
                    _files = new List<MOJFile>(_files.OrderBy(f => f.FileType));
                }
            }
            catch (Exception ex)
            {
                GlobalVars.TheHost.ReportError(new ErrorReporter()
                {
                    ErrorMessage = "Error loading movie from database",
                    ErrorDetails = ex.ToString(),
                    ErrorCode = "GetDBMovie",
                });
            }
        }

        public string MovieCoverPath
        {
            get
            {
                MOJBasicFileClass FILE;

                if (_files.Where(f => f.FileID == this.CoverID).Count() == 1)
                {
                    FILE = _files.Where(f => f.FileID == this.CoverID).First();
                    return FILE.FileFullPath;
                }
                else
                {
                    return MojWebImage.CreateNoPosterImage().OriginalPath;
                }
            }
        }
        public List<MOJFile> Files
        { get { return _files; } }

        public List<MOJFile> MovieFiles
        { get { return new List<MOJFile>(_files.Where(f => f.FileType == 0)); } }
        public List<MOJFile> SubtitleFiles
        { get { return new List<MOJFile>(_files.Where(f => f.FileType == 1)); } }
        public List<MOJFile> ImageFiles
        { get { return new List<MOJFile>(_files.Where(f => f.FileType == 2)); } }

        public BitmapImage Cover
        {
            get
            {
                if(ImageFiles.Count > 0)
                    return new BitmapImage(new Uri(ImageFiles[0].FileFullPath));

                return null;
            }
        }

        public string Query
        {
            get
            {
                string q = MovieCode + MovieTitle + OriginalTitle + MovieYear + MovieGenres +
                    MovieCast + MovieDirectors + MovieWriters + IMDBID + Tagline;

                return q.ToLower();
            }
        }

        public bool TestFilter(MOJFilter Filter)
        {
            string query = Filter.Query.ToLower();

            switch (Filter.Field)
            {
                case MojMovieField.AllFields:
                    return Query.ToLower().IndexOf(query) != -1;
                case MojMovieField.MovieCast:
                    return MovieCast.ToLower().IndexOf(query) != -1;
                case MojMovieField.MovieDirector:
                    return MovieDirectors.ToLower().IndexOf(query) != -1;
                case MojMovieField.MovieGenres:
                    return MovieGenres.ToLower().IndexOf(query) != -1;
                case MojMovieField.MovieTitle:
                    return MovieTitle.ToLower().IndexOf(query) != -1;
                case MojMovieField.MovieWriter:
                    return MovieWriters.ToLower().IndexOf(query) != -1;
                case MojMovieField.MovieYear:
                    return MovieYear.ToLower().IndexOf(query) != -1;
                default:
                    return false;
            }
        }
        public bool TestPool(MOJFilterPool Pool)
        {
            foreach (var v in Pool.AndFilters)
                if (!TestFilter(v))
                    return false;

            if (Pool.OrFilters.Count == 0)
                return true;

            foreach (var v in Pool.OrFilters)
                if (TestFilter(v))
                    return true;

            return false;
        }
        public bool ContainsSubtitle(ISO639_1 Lang)
        {
            foreach (var v in SubtitleFiles)
                if (v.ISO639_Code == Lang.Index)
                    return true;

            return false;
        }

        public string ImdbUrl
        { get { return "http://www.imdb.com/title/" + this.IMDBID; } }
        public string TheMovieDbUrl
        { get { return "http://www.themoviedb.org/movie/" + this.MovieCode; } }

        public bool IsOrganized
        {
            get
            {
                foreach (var f in Files)
                {
                    if (f.FileType != 2 && !f.IsOrganized)
                        return false;
                }

                return true;
            }
        }
        public bool IsAvaible
        {
            get
            {
                foreach (var v in Files)
                    if (!v.IsAvaible)
                        return false;

                return true;
            }
        }

        public int CompareTo(object obj)
        {
            MOJMovie m = obj as MOJMovie;
            return this.MovieTitle.CompareTo(m.MovieTitle);
        }
    }

    public enum MojMovieField
    {
        MovieTitle,
        MovieYear,
        MovieDirector,
        MovieWriter,
        MovieGenres,
        MovieCast,
        AllFields,
    }
    public class MOJFilter
    {
        private bool _bool;

        public MOJFilter(MojMovieField field, string query, bool matchAllways)
        {
            Field = field;
            Query = query;
            _bool = matchAllways;
        }

        public MojMovieField Field
        { get; set; }
        public string Query
        { get; set; }
        public bool MatchAllways
        { get { return _bool; } }
        public int FilterIndex
        { get; set; }
    }
    public class MOJFilterPool
    {
        private List<MOJFilter> _list;
        private List<MOJFilter> _listAnd;
        private List<MOJFilter> _listOr;

        public MOJFilterPool()
        {
            _list = new List<MOJFilter>();
            SetLists();
        }
        private void SetLists()
        {
            _listAnd = new List<MOJFilter>(_list.Where(e => e.MatchAllways));
            _listOr = new List<MOJFilter>(_list.Where(e => !e.MatchAllways));
        }

        public List<MOJFilter> Filters
        { get { return _list; } }
        public List<MOJFilter> AndFilters
        { get { return _listAnd; } }
        public List<MOJFilter> OrFilters
        { get { return _listOr; } }

        public void AddNewFilter(MOJFilter Filter)
        {
            _list.Add(Filter);

            int last = _list.Count - 1;
            _list[last].FilterIndex = last;

            SetLists();
        }
        public void RemoveFilter(MOJFilter Filter)
        {
            _list.RemoveAt(Filter.FilterIndex);
            SetLists();
        }
    }
}
